package com.relytosoft.mizar.media.display.services.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.relytosoft.dubhe.common.core.exception.ServiceException;
import com.relytosoft.dubhe.common.core.utils.TreeBuildUtils;
import com.relytosoft.mizar.media.common.config.properties.MizarTransProperties;
import com.relytosoft.mizar.media.common.utils.TransRequestUtil;
import com.relytosoft.mizar.media.display.api.feign.VideoTransFeignService;
import com.relytosoft.mizar.media.display.api.pojo.query.ChannelPlayDetailQuery;
import com.relytosoft.mizar.media.display.api.pojo.vo.VideoChannelVo;
import com.relytosoft.mizar.media.display.api.pojo.vo.VideoPlayVo;
import com.relytosoft.mizar.media.display.services.mapper.VideoChannelMapper;
import com.relytosoft.mizar.media.display.services.service.VideoService;
import com.relytosoft.mizar.media.display.services.utils.ResponseUtils;
import com.relytosoft.mizar.media.external.api.display.request.ManualVideoDto;
import com.relytosoft.mizar.media.external.api.display.request.ReplayTheaterDto;
import com.relytosoft.mizar.media.external.api.display.response.VideoClipInfoDto;
import com.relytosoft.mizar.media.external.api.display.service.PtzOperationService;
import com.relytosoft.mizar.media.external.api.display.service.ReplayTheaterService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * VideoServiceImpl
 *
 * @Author SunLi
 * @Date: 2022/4/18 13:45
 * @Version 1.0
 */
@Service
public class VideoServiceImpl extends ServiceImpl<VideoChannelMapper, VideoChannelVo> implements VideoService {
    @Resource
    private PtzOperationService ptzOperationService;

    @Resource
    private MizarTransProperties transProperties;
    @Resource
    private VideoTransFeignService transFeignService;

    @Resource
    private ReplayTheaterService replayTheaterService;

    @Override
    public List<VideoChannelVo> selectVideoChannelList(Integer districtId, String name) {
        List<VideoChannelVo> videoChannelVoList = baseMapper.selectVideoChannelList(districtId, name, "HK");
        if (districtId == null || districtId == 0) {
            VideoChannelVo root = new VideoChannelVo();
            root.setId(0);
            root.setName("区域");
            root.setParentId(-1);
            root.setType(1);
            root.setSort(0);
            videoChannelVoList.add(0, root);
        }
        return videoChannelVoList;
    }

    @Override
    public List<Tree<Integer>> buildVideoChannelListTree(List<VideoChannelVo> videoChannelVoList) {
        if (CollUtil.isEmpty(videoChannelVoList)) {
            return CollUtil.newArrayList();
        }
        return TreeBuildUtils.build(videoChannelVoList, (v, tree) -> {
            tree.setId(v.getId());
            tree.setParentId(v.getParentId());
            tree.setName(v.getName());
            tree.setWeight(-v.getSort());
            tree.put("type", v.getType());
            tree.put("channelId", v.getChannelId());
            tree.put("channelMainRtspUrl", v.getChannelMainRtspUrl());
            tree.put("channelSubRtspUrl", v.getChannelSubRtspUrl());
            tree.put("platformChannelCode", v.getPlatformChannelCode());
        });
    }

    @Override
    public String manualCapture(String channelIndexCode) {
        return ptzOperationService.manualCapture(channelIndexCode);
    }

    /**
     * 构件播放码流
     *
     * @param channelPlayDetailList
     * @return List<VideoPlayVo>
     * @author jgg
     */
    @Override
    public List<VideoPlayVo> buildPlayStreamUrl(List<ChannelPlayDetailQuery> channelPlayDetailList) {
        List<VideoPlayVo> rotaPlayVoList = new ArrayList<>();
        //webrtc播放URL
        String strTmp = "http://%s/index/api/webrtc?app=%s&stream=%s&type=play";
        //rtmp URL rtmp://ip/app/stream
        //rtmp对应的http-flv、websocket URL
        //ws URL  ws://ip/app/stream.app.flv 示例ws://127.0.0.1/live/0.live.flv
        //flv URL http://ip/app/stream.app.flv示例http://127.0.0.1/live/0.live.flv
        if (channelPlayDetailList != null && channelPlayDetailList.size() > 0) {
            channelPlayDetailList.forEach(e -> {
                VideoPlayVo rotaPlayVo = new VideoPlayVo();
                String streamRtspUrl = e.getStreamRtspUrl();
                Integer channelId = e.getChannelId();
                if (StrUtil.isNotBlank(streamRtspUrl) && channelId != null) {
                    //将RTSP URL经转码服务器进行拉流
                    String res = TransRequestUtil.handlerResponse(
                            transFeignService.addStreamProxy(transProperties.getAppSecret(),
                                    "0",
                                    "live",
                                    channelId.toString(),
                                    streamRtspUrl, 1, 0)
                    );
                    rotaPlayVo.setPlayStreamKey(ResponseUtils.getStreamProxyKey(res));
                    //封装为前端可播放的URL
                    rotaPlayVo.setPlayStreamUrl(String.format(strTmp, transProperties.getPlayUrl(), "live", e.getChannelId()));
                } else {
                    rotaPlayVo.setPlayStreamUrl("");
                    rotaPlayVo.setPlayStreamKey("");
                }
                rotaPlayVo.setChannelId(e.getChannelId());

                rotaPlayVoList.add(rotaPlayVo);
            });
        }
        return rotaPlayVoList;
    }

    @Override
    public VideoClipInfoDto buildReplayTheaterStreamUrl(ReplayTheaterDto replayTheaterDto, String channelId) {
        replayTheaterDto.setExpand("transcode=1&videotype=h264");
        replayTheaterDto.setProtocol("rtsp");
        replayTheaterDto.setLockType(0);
        VideoClipInfoDto videoClipInfoDto = replayTheaterService.selectReplayTheater(replayTheaterDto);
        String url = videoClipInfoDto.getUrl();
        System.out.println("海康地址=======" + url);
        String strTmp = "http://%s/%s/%s.live.flv?vhost=%s";
        String vhost = "0";
        String app = "replay";
        String stream = System.currentTimeMillis() + "";
        String appSecret = transProperties.getAppSecret();
        if (!StrUtil.isEmptyIfStr(url)) {
            String res;
            try {
                //将RTSP URL经转码服务器进行拉流
                res = TransRequestUtil.handlerResponse(transFeignService.addStreamProxy(
                        appSecret,
                        vhost,
                        app,
                        stream,
                        url,
                        0,
                        1));
            } catch (ServiceException serviceException) {
                throw new ServiceException("已有在播放的流，关闭后再试" + "---" + serviceException.getMessage());
            }
            //转码后关闭流的key
            videoClipInfoDto.setPlayStreamKey(ResponseUtils.getStreamProxyKey(res));
            System.out.println("key==========="+ResponseUtils.getStreamProxyKey(res));
            //封装为前端可播放的URL
            videoClipInfoDto.setUrl(String.format(strTmp, transProperties.getPlayUrl(), app, stream, vhost));
            videoClipInfoDto.setApp(app);
            videoClipInfoDto.setStream(stream);
            videoClipInfoDto.setVhost(vhost);
            videoClipInfoDto.setSchema("rtmp");
            System.out.println(videoClipInfoDto.getUrl());
            videoClipInfoDto.setPlayStreamKey(ResponseUtils.getStreamProxyKey(res));
        }
        return videoClipInfoDto;
    }

    @Override
    public Map<String, String> manualVideo(ManualVideoDto manualVideoDto) {
        String taskId = replayTheaterService.manualVideo(manualVideoDto);
        HashMap<String, String> map = new HashMap<>(55);
        map.put("taskId", taskId);
        return map;
    }

    @Override
    public String stopManualVideo(List<Map<String, Object>> maps) {
        int success = 0;
        List<JSONObject> list = new ArrayList<>();
        if (maps.size() > 0) {
            for (Map<String, Object> map : maps) {
                try {
                    String msg = replayTheaterService.stopManualVideo(map);
                    if ("success".equals(msg)) {
                        success++;
                    }
                } catch (ServiceException e) {
                    list.add(JSONObject.parseObject(e.getMessage()));
                }
            }
        }
        return "success:" + success + "——" + "fail:" + list.size() + ":reason" + JSONObject.toJSONString(list);
    }


    @Override
    public void closeStream(String playStreamKey) {
        String response = TransRequestUtil.handlerResponse(transFeignService.closeStram(transProperties.getAppSecret(), playStreamKey));
        System.out.println(response);
    }
}